home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Sound / MusicIn / musicin.c < prev    next >
C/C++ Source or Header  |  1997-09-23  |  39KB  |  1,028 lines

  1. /**********************************************************************
  2. Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
  3. musicin.c
  4. **********************************************************************/
  5. /**********************************************************************
  6.  * MPEG/audio coding/decoding software, work in progress              *
  7.  *   NOT for public distribution until verified and approved by the   *
  8.  *   MPEG/audio committee.  For further information, please contact   *
  9.  *   Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com             *
  10.  *                                                                    *
  11.  * VERSION 4.0                                                        *
  12.  *   changes made since last update:                                  *
  13.  *   date   programmers         comment                               *
  14.  * 3/01/91  Douglas Wong,       start of version 1.1 records          *
  15.  *          Davis Pan                                                 *
  16.  * 3/06/91  Douglas Wong,       rename: setup.h to endef.h            *
  17.  *                              removed extraneous variables          *
  18.  * 3/21/91  J.Georges Fritsch   introduction of the bit-stream        *
  19.  *                              package. This package allows you      *
  20.  *                              to generate the bit-stream in a       *
  21.  *                              binary or ascii format                *
  22.  * 3/31/91  Bill Aspromonte     replaced the read of the SB matrix    *
  23.  *                              by an "code generated" one            *
  24.  * 5/10/91  W. Joseph Carter    Ported to Macintosh and Unix.         *
  25.  *                              Incorporated Jean-Georges Fritsch's   *
  26.  *                              "bitstream.c" package.                *
  27.  *                              Modified to strictly adhere to        *
  28.  *                              encoded bitstream specs, including    *
  29.  *                              "Berlin changes".                     *
  30.  *                              Modified user interface dialog & code *
  31.  *                              to accept any input & output          *
  32.  *                              filenames desired.  Also added        *
  33.  *                              de-emphasis prompt and final bail-out *
  34.  *                              opportunity before encoding.          *
  35.  *                              Added AIFF PCM sound file reading     *
  36.  *                              capability.                           *
  37.  *                              Modified PCM sound file handling to   *
  38.  *                              process all incoming samples and fill *
  39.  *                              out last encoded frame with zeros     *
  40.  *                              (silence) if needed.                  *
  41.  *                              Located and fixed numerous software   *
  42.  *                              bugs and table data errors.           *
  43.  * 27jun91  dpwe (Aware Inc)    Used new frame_params struct.         *
  44.  *                              Clear all automatic arrays.           *
  45.  *                              Changed some variable names,          *
  46.  *                              simplified some code.                 *
  47.  *                              Track number of bits actually sent.   *
  48.  *                              Fixed padding slot, stereo bitrate    *
  49.  *                              Added joint-stereo : scales L+R.      *
  50.  * 6/12/91  Earle Jennings      added fix for MS_DOS in obtain_param  *
  51.  * 6/13/91  Earle Jennings      added stack length adjustment before  *
  52.  *                              main for MS_DOS                       *
  53.  * 7/10/91  Earle Jennings      conversion of all float to FLOAT      *
  54.  *                              port to MsDos from MacIntosh completed*
  55.  * 8/ 8/91  Jens Spille         Change for MS-C6.00                   *
  56.  * 8/22/91  Jens Spille         new obtain_parameters()               *
  57.  *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           *
  58.  *          Don H. Lee,                                               *
  59.  *          Peter W. Farrett                                          *
  60.  *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   *
  61.  *                              newly introduced functions are        *
  62.  *                              I_CRC_calc, II_CRC_calc and encode_CRC*
  63.  *                              Additions and revisions are marked    *
  64.  *                              with "dhl" for clarity                *
  65.  *11/11/91 Katherine Wang       Documentation of code.                *
  66.  *                                (variables in documentation are     *
  67.  *                                surround by the # symbol, and an '*'*
  68.  *                                denotes layer I or II versions)     *
  69.  * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
  70.  *                              important fixes involved changing     *
  71.  *                              16-bit ints to long or unsigned in    *
  72.  *                              bit alloc routines for quant of 65535 *
  73.  *                              and passing proper function args.     *
  74.  *                              Removed "Other Joint Stereo" option   *
  75.  *                              and made bitrate be total channel     *
  76.  *                              bitrate, irrespective of the mode.    *
  77.  *                              Fixed many small bugs & reorganized.  *
  78.  * 2/25/92  Masahiro Iwadare    made code cleaner and more consistent *
  79.  * 8/07/92  Mike Coleman        make exit() codes return error status *
  80.  *                              made slight changes for portability   *
  81.  *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  *
  82.  * 8/25/92  Shaun Astarabadi    Replaced rint() function with explicit*
  83.  *                              rounding for portability with MSDOS.  *
  84.  * 9/22/92  jddevine@aware.com  Fixed _scale_factor_calc() calls.     *
  85.  *10/19/92  Masahiro Iwadare    added info->mode and info->mode_ext   *
  86.  *                              updates for AIFF format files         *
  87.  * 3/10/93  Kevin Peterson      In parse_args, only set non default   *
  88.  *                              bit rate if specified in arg list.    *
  89.  *                              Use return value from aiff_read_hdrs  *
  90.  *                              to fseek to start of sound data       *
  91.  * 7/26/93  Davis Pan           fixed bug in printing info->mode_ext  *
  92.  *                              value for joint stereo condition      *
  93.  * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        *
  94.  *         Daniel Lauzon, and                                         *
  95.  *         Bill Truerniet                                             *
  96.  * 20/08/1996 Stephane TAVENARD added -i option (to set private bit)  *
  97.  **********************************************************************/
  98.  
  99. #ifdef MS_DOS
  100. #include <dos.h>
  101. #endif
  102. #include "common.h"
  103. #include "encoder.h"
  104.  
  105. #ifdef UNIX
  106. #include <time.h>
  107. #endif
  108.  
  109. /* Global variable definitions for "musicin.c" */
  110.  
  111. FILE               *musicin;
  112. Bit_stream_struc   bs;
  113. char               *programName;
  114.  
  115. /* Implementations */
  116.  
  117. /************************************************************************
  118. /*
  119. /* obtain_parameters
  120. /*
  121. /* PURPOSE:  Prompts for and reads user input for encoding parameters
  122. /*
  123. /* SEMANTICS:  The parameters read are:
  124. /* - input and output filenames
  125. /* - sampling frequency (if AIFF file, will read from the AIFF file header)
  126. /* - layer number
  127. /* - mode (stereo, joint stereo, dual channel or mono)
  128. /* - psychoacoustic model (I or II)
  129. /* - total bitrate, irrespective of the mode
  130. /* - de-emphasis, error protection, copyright and original or copy flags
  131. /*
  132. /************************************************************************/
  133.  
  134. void
  135. obtain_parameters(fr_ps,psy,num_samples,original_file_name,encoded_file_name)
  136. frame_params    *fr_ps;
  137. int             *psy;
  138. unsigned long   *num_samples;
  139. char            original_file_name[MAX_NAME_SIZE];
  140. char            encoded_file_name[MAX_NAME_SIZE];
  141. {
  142.     int j;
  143.     long int freq;
  144.     int model, brt;
  145.     char t[50];
  146.     IFF_AIFF pcm_aiff_data;
  147.     layer *info = fr_ps->header;
  148.     long soundPosition;
  149.  
  150.     do  {
  151.        printf("Enter PCM input file name <required>: ");
  152.        gets(original_file_name);
  153.        if (original_file_name[0] == NULL_CHAR)
  154.        printf("PCM input file name is required.\n");
  155.     } while (original_file_name[0] == NULL_CHAR);
  156.     printf(">>> PCM input file name is: %s\n", original_file_name);
  157.  
  158.     if ((musicin = fopen(original_file_name, "rb")) == NULL) {
  159.        printf("Could not find \"%s\".\n", original_file_name);
  160.        exit(1);
  161.     }
  162.  
  163. #ifdef  MS_DOS
  164.     printf("Enter MPEG encoded output file name <%s>: ",
  165.            new_ext(original_file_name, DFLT_EXT)); /* 92-08-19 shn */
  166. #else
  167.     printf("Enter MPEG encoded output file name <%s%s>: ",
  168.            original_file_name, DFLT_EXT);
  169. #endif
  170.  
  171.     gets(encoded_file_name);
  172.     if (encoded_file_name[0] == NULL_CHAR) {
  173. #ifdef  MS_DOS
  174.         /* replace old extension with new one, 92-08-19 shn */
  175.         strcpy(encoded_file_name,new_ext(original_file_name, DFLT_EXT));
  176. #else
  177.         strcat(strcpy(encoded_file_name, original_file_name), DFLT_EXT);
  178. #endif
  179.     }
  180.         
  181.  
  182.     printf(">>> MPEG encoded output file name is: %s\n", encoded_file_name);
  183.  
  184.     open_bit_stream_w(&bs, encoded_file_name, BUFFER_SIZE);
  185.  
  186.     if ((soundPosition = aiff_read_headers(musicin, &pcm_aiff_data)) != -1) {
  187.  
  188.        printf(">>> Using Audio IFF sound file headers\n");
  189.  
  190.        aiff_check(original_file_name, &pcm_aiff_data);
  191.  
  192.        if (fseek(musicin, soundPosition, SEEK_SET) != 0) {
  193.           printf("Could not seek to PCM sound data in \"%s\".\n",
  194.                  original_file_name);
  195.           exit(1);
  196.        }
  197.  
  198.        info->sampling_frequency = SmpFrqIndex((long)pcm_aiff_data.sampleRate);
  199.        printf(">>> %.f Hz sampling frequency selected\n",
  200.               pcm_aiff_data.sampleRate);
  201.  
  202.        /* Determine number of samples in sound file */
  203. #ifndef MS_DOS
  204.        *num_samples = pcm_aiff_data.numChannels *
  205.                       pcm_aiff_data.numSampleFrames;
  206. #else
  207.        *num_samples = (long)(pcm_aiff_data.numChannels) *
  208.                       (long)(pcm_aiff_data.numSampleFrames);
  209. #endif
  210.  
  211.     }
  212.     else {    /* Not using Audio IFF sound file headers. */
  213.  
  214.        printf("What is the sampling frequency? <44100>[Hz]: ");
  215.        gets(t);
  216.        freq = atol(t);
  217.        switch (freq) {
  218.           case 48000 : info->sampling_frequency = 1;
  219.               printf(">>> %ld Hz sampling freq selected\n", freq);
  220.               break;
  221.           case 44100 : info->sampling_frequency = 0;
  222.               printf(">>> %ld Hz sampling freq selected\n", freq);
  223.               break;
  224.           case 32000 : info->sampling_frequency = 2;
  225.               printf(">>> %ld Hz sampling freq selected\n", freq);
  226.               break;
  227.           default:    info->sampling_frequency = 0;
  228.               printf(">>> Default 44.1 kHz samp freq selected\n");
  229.        }
  230.  
  231.        if (fseek(musicin, 0, SEEK_SET) != 0) {
  232.           printf("Could not seek to PCM sound data in \"%s\".\n",
  233.                   original_file_name);
  234.           exit(1);
  235.        }
  236.  
  237.        /* Declare sound file to have "infinite" number of samples. */
  238.        *num_samples = MAX_U_32_NUM;
  239.  
  240.     }
  241.  
  242.     printf("Which layer do you want to use?\n");
  243.     printf("Available: Layer (1), Layer (<2>): ");
  244.     gets(t);
  245.     switch(*t){
  246.        case '1': info->lay = 1; printf(">>> Using Layer %s\n",t); break;
  247.        case '2': info->lay = 2; printf(">>> Using Layer %s\n",t); break;
  248.        default:  info->lay = 2; printf(">>> Using default Layer 2\n"); break;
  249.     }
  250.  
  251.     printf("Which mode do you want?\n");
  252.     printf("Available: (<s>)tereo, (j)oint stereo, ");
  253.     printf("(d)ual channel, s(i)ngle Channel: ");
  254.     gets(t);
  255.     switch(*t){
  256.        case 's':
  257.        case 'S':
  258.           info->mode = MPG_MD_STEREO; info->mode_ext = 0;
  259.           printf(">>> Using mode %s\n",t);
  260.           break;
  261.        case 'j':
  262.        case 'J':
  263.           info->mode = MPG_MD_JOINT_STEREO;
  264.           printf(">>> Using mode %s\n",t);
  265.           break;
  266.        case 'd':
  267.        case 'D':
  268.           info->mode = MPG_MD_DUAL_CHANNEL; info->mode_ext = 0;
  269.           printf(">>> Using mode %s\n",t);
  270.           break;
  271.        case 'i':
  272.        case 'I':
  273.           info->mode = MPG_MD_MONO; info->mode_ext = 0;
  274.           printf(">>> Using mode %s\n",t);
  275.           break;
  276.        default:
  277.           info->mode = MPG_MD_STEREO; info->mode_ext = 0;
  278.           printf(">>> Using default stereo mode\n");
  279.           break;
  280.     }
  281.  
  282.     printf("Which psychoacoustic model do you want to use? <2>: ");
  283.     gets(t);
  284.     model = atoi(t);
  285.     if (model > 2 || model < 1) {
  286.        printf(">>> Default model 2 selected\n");
  287.        *psy = 2;
  288.     }
  289.     else {
  290.        *psy = model;
  291.        printf(">>> Using psychoacoustic model %d\n", model);
  292.     }
  293.  
  294.     printf("What is the total bitrate? <%u>[kbps]: ", DFLT_BRT);
  295.     gets(t);
  296.     brt = atoi(t);
  297.     if (brt == 0) brt = -10;
  298.     j=0;
  299.     while (j<15) {
  300.        if (bitrate[info->lay-1][j] == brt) break;
  301.        j++;
  302.     }
  303.     if (j==15) {
  304.        printf(">>> Using default %u kbps\n", DFLT_BRT);
  305.        for (j=0;j<15;j++)
  306.           if (bitrate[info->lay-1][j] == DFLT_BRT) {
  307.              info->bitrate_index = j;
  308.              break;
  309.           }
  310.     }
  311.     else{
  312.        info->bitrate_index = j;
  313.        printf(">>> Bitrate = %d kbps\n", bitrate[info->lay-1][j]);
  314.     }
  315.  
  316.     printf("What type of de-emphasis should the decoder use?\n");
  317.     printf("Available: (<n>)one, (5)0/15 microseconds, (c)citt j.17: ");
  318.     gets(t);
  319.     if (*t != 'n' && *t != '5' && *t != 'c') {
  320.        printf(">>> Using default no de-emphasis\n");
  321.        info->emphasis = 0;
  322.     }
  323.     else {
  324.        if (*t == 'n')      info->emphasis = 0;
  325.        else if (*t == '5') info->emphasis = 1;
  326.        else if (*t == 'c') info->emphasis = 3;
  327.        printf(">>> Using de-emphasis %s\n",t);
  328.     }
  329.  
  330. /*  Start 2. Part changes for CD Ver 3.2; jsp; 22-Aug-1991 */
  331.  
  332.     printf("Do you want to set the private bit? (y/<n>): ");
  333.     gets(t);
  334.     if (*t == 'y' || *t == 'Y') info->extension = 1;
  335.     else                        info->extension = 0;
  336.     if(info->extension) printf(">>> Private bit set\n");
  337.     else                printf(">>> Private bit not set\n");
  338.  
  339. /*  End changes for CD Ver 3.2; jsp; 22-Aug-1991 */
  340.  
  341.     printf("Do you want error protection? (y/<n>): ");
  342.     gets(t);
  343.     if (*t == 'y' || *t == 'Y') info->error_protection = TRUE;
  344.     else                        info->error_protection = FALSE;
  345.     if(info->error_protection) printf(">>> Error protection used\n");
  346.     else printf(">>> Error protection not used\n");
  347.  
  348.     printf("Is the material copyrighted? (y/<n>): ");
  349.     gets(t);
  350.     if (*t == 'y' || *t == 'Y') info->copyright = 1;
  351.     else                        info->copyright = 0;
  352.     if(info->copyright) printf(">>> Copyrighted material\n");
  353.     else                printf(">>> Material not copyrighted\n");
  354.  
  355.     printf("Is this the original? (y/<n>): ");
  356.     gets(t);
  357.     if (*t == 'y' || *t == 'Y') info->original = 1;
  358.     else                        info->original = 0;
  359.     if(info->original) printf(">>> Original material\n");
  360.     else               printf(">>> Material not original\n");
  361.  
  362.     printf("Do you wish to exit (last chance before encoding)? (y/<n>): ");
  363.     gets(t);
  364.     if (*t == 'y' || *t == 'Y') exit(0);
  365. }
  366.  
  367. /************************************************************************
  368. /*
  369. /* parse_args
  370. /*
  371. /* PURPOSE:  Sets encoding parameters to the specifications of the
  372. /* command line.  Default settings are used for parameters
  373. /* not specified in the command line.
  374. /*
  375. /* SEMANTICS:  The command line is parsed according to the following
  376. /* syntax:
  377. /*
  378. /* -l  is followed by the layer number
  379. /* -m  is followed by the mode
  380. /* -p  is followed by the psychoacoustic model number
  381. /* -s  is followed by the sampling rate
  382. /* -b  is followed by the total bitrate, irrespective of the mode
  383. /* -d  is followed by the emphasis flag
  384. /* -c  is followed by the copyright/no_copyright flag
  385. /* -o  is followed by the original/not_original flag
  386. /* -e  is followed by the error_protection on/off flag
  387. /*
  388. /* If the input file is in AIFF format, the sampling frequency is read
  389. /* from the AIFF header.
  390. /*
  391. /* The input and output filenames are read into #inpath# and #outpath#.
  392. /*
  393. /************************************************************************/
  394.  
  395. void
  396. parse_args(argc, argv, fr_ps, psy, num_samples, inPath, outPath)
  397. int     argc;
  398. char    **argv;
  399. frame_params  *fr_ps;
  400. int     *psy;
  401. unsigned long *num_samples;
  402. char    inPath[MAX_NAME_SIZE];
  403. char    outPath[MAX_NAME_SIZE];
  404. {
  405.    FLOAT srate;
  406.    int   brate;
  407.    layer *info = fr_ps->header;
  408.    int   err = 0, i = 0;
  409.    IFF_AIFF pcm_aiff_data;
  410.    long samplerate;
  411.    long soundPosition;
  412.  
  413.    /* preset defaults */
  414.    inPath[0] = '\0';   outPath[0] = '\0';
  415.    info->lay = DFLT_LAY;
  416.    info->copyright = 0;
  417.    info->original  = 0;
  418.    info->error_protection = FALSE;
  419.    info->extension = 0;
  420.    
  421.    switch(DFLT_MOD) {
  422.       case 's': info->mode = MPG_MD_STEREO; info->mode_ext = 0; break;
  423.       case 'd': info->mode = MPG_MD_DUAL_CHANNEL; info->mode_ext=0; break;
  424.       case 'j': info->mode = MPG_MD_JOINT_STEREO; break;
  425.       case 'm': info->mode = MPG_MD_MONO; info->mode_ext = 0; break;
  426.       default:
  427.          fprintf(stderr, "%s: Bad mode dflt %c\n", programName, DFLT_MOD);
  428.          abort();
  429.    }
  430.    *psy = DFLT_PSY;
  431.    if((info->sampling_frequency = SmpFrqIndex((long)(1000*DFLT_SFQ))) < 0) {
  432.       fprintf(stderr, "%s: bad sfrq default %.2f\n", programName, DFLT_SFQ);
  433.       abort();
  434.    }
  435.    if((info->bitrate_index = BitrateIndex(info->lay, DFLT_BRT)) < 0) {
  436.       fprintf(stderr, "%s: bad default bitrate %u\n", programName, DFLT_BRT);
  437.       abort();
  438.    }
  439.    switch(DFLT_EMP) {
  440.       case 'n': info->emphasis = 0; break;
  441.       case '5': info->emphasis = 1; break;
  442.       case 'c': info->emphasis = 3; break;
  443.       default: 
  444.          fprintf(stderr, "%s: Bad emph dflt %c\n", programName, DFLT_EMP);
  445.          abort();
  446.    }
  447.    info->copyright = 0; info->original = 0; info->error_protection = FALSE;
  448.  
  449.    /* process args */
  450.    while(++i<argc && err == 0) {
  451.       char c, *token, *arg, *nextArg;
  452.       int  argUsed;
  453.  
  454.       token = argv[i];
  455.       if(*token++ == '-') {
  456.          if(i+1 < argc) nextArg = argv[i+1];
  457.          else           nextArg = "";
  458.          argUsed = 0;
  459.          while(c = *token++) {
  460.             if(*token /* NumericQ(token) */) arg = token;
  461.             else                             arg = nextArg;
  462.             switch(c) {
  463.                case 'l':        info->lay = atoi(arg); argUsed = 1;
  464.                   if(info->lay<1 || info->lay>2) {
  465.                      fprintf(stderr,"%s: -l layer must be 1 or 2, not %s\n",
  466.                           programName, arg);
  467.                      err = 1;
  468.                   }
  469.                   break;
  470.                case 'm':        argUsed = 1;
  471.                   if (*arg == 's')
  472.                     { info->mode = MPG_MD_STEREO; info->mode_ext = 0; }
  473.                   else if (*arg == 'd')
  474.                     { info->mode = MPG_MD_DUAL_CHANNEL; info->mode_ext=0; }
  475.                   else if (*arg == 'j')
  476.                     { info->mode = MPG_MD_JOINT_STEREO; }
  477.                   else if (*arg == 'm')
  478.                     { info->mode = MPG_MD_MONO; info->mode_ext = 0; }
  479.                   else {
  480.                     fprintf(stderr,"%s: -m mode must be s/d/j/m not %s\n",
  481.                             programName, arg);
  482.                     err = 1;
  483.                   }
  484.                   break;
  485.                case 'p':        *psy = atoi(arg); argUsed = 1;
  486.                   if(*psy<1 || *psy>2) {
  487.                      fprintf(stderr,"%s: -p model must be 1 or 2, not %s\n",
  488.                              programName, arg);
  489.                      err = 1;
  490.                   }
  491.                   break;
  492.  
  493.                case 's':
  494.                   argUsed = 1;
  495.                   srate = atof( arg );
  496.                   /* samplerate = rint( 1000.0 * srate ); $A  */
  497.                   samplerate = (long) (( 1000.0 * srate ) + 0.5);
  498.                   if( (info->sampling_frequency = SmpFrqIndex((long) samplerate)) < 0 )
  499.                       err = 1;
  500.                   break;
  501.                   
  502.                case 'b':        
  503.              argUsed = 1;
  504.           brate = atoi(arg); 
  505.           if( (info->bitrate_index = BitrateIndex(info->lay, brate)) < 0)
  506.              err=1;                  
  507.          break;
  508.                case 'd':        argUsed = 1;
  509.                   if (*arg == 'n')                    info->emphasis = 0;
  510.                   else if (*arg == '5')               info->emphasis = 1;
  511.                   else if (*arg == 'c')               info->emphasis = 3;
  512.                   else {
  513.                      fprintf(stderr,"%s: -d emp must be n/5/c not %s\n",
  514.                              programName, arg);
  515.                      err = 1;
  516.                   }
  517.                   break;
  518.                 case 'c':       info->copyright = 1; break;
  519.                 case 'o':       info->original  = 1; break;
  520.                 case 'e':       info->error_protection = TRUE; break;
  521.                 case 'i':       info->extension = 1; break;
  522.                 default:        fprintf(stderr,"%s: unrec option %c\n",
  523.                                         programName, c);
  524.                                 err = 1; break;
  525.             }
  526.             if(argUsed) {
  527.                if(arg == token)    token = "";   /* no more from token */
  528.                else                ++i;          /* skip arg we used */
  529.                arg = ""; argUsed = 0;
  530.             }
  531.          }
  532.       }
  533.       else {
  534.          if(inPath[0] == '\0')       strcpy(inPath, argv[i]);
  535.          else if(outPath[0] == '\0') strcpy(outPath, argv[i]);
  536.          else {
  537.             fprintf(stderr,"%s: excess arg %s\n", programName, argv[i]);
  538.             err = 1;
  539.          }
  540.       }
  541.    }
  542.  
  543.    if(err || inPath[0] == '\0') usage();  /* never returns */
  544.  
  545.    if(outPath[0] == '\0') {
  546.       strcpy(outPath, inPath);
  547.       strcat(outPath, DFLT_EXT);
  548.    }
  549.  
  550.    if ((musicin = fopen(inPath, "rb")) == NULL) {
  551.       printf("Could not find \"%s\".\n", inPath);
  552.       exit(1);
  553.    }
  554.    
  555.    open_bit_stream_w(&bs, outPath, BUFFER_SIZE);
  556.  
  557.    if ((soundPosition = aiff_read_headers(musicin, &pcm_aiff_data)) != -1) {
  558.  
  559.       printf(">>> Using Audio IFF sound file headers\n");
  560.  
  561.       aiff_check(inPath, &pcm_aiff_data);
  562.  
  563.       if (fseek(musicin, soundPosition, SEEK_SET) != 0) {
  564.          printf("Could not seek to PCM sound data in \"%s\".\n", inPath);
  565.          exit(1);
  566.       }
  567.  
  568.       info->sampling_frequency = SmpFrqIndex((long)pcm_aiff_data.sampleRate);
  569.       printf(">>> %.f Hz sampling frequency selected\n",
  570.              pcm_aiff_data.sampleRate);
  571.  
  572.       /* Determine number of samples in sound file */
  573. #ifndef MS_DOS
  574.       *num_samples = pcm_aiff_data.numChannels *
  575.                      pcm_aiff_data.numSampleFrames;
  576. #else
  577.       *num_samples = (long)(pcm_aiff_data.numChannels) *
  578.                      (long)(pcm_aiff_data.numSampleFrames);
  579. #endif
  580.       if ( pcm_aiff_data.numChannels == 1 ) {
  581.         info->mode = MPG_MD_MONO;
  582.         info->mode_ext = 0;
  583.       }
  584.    }
  585.    else {    /* Not using Audio IFF sound file headers. */
  586.  
  587.       if (fseek(musicin, 0, SEEK_SET) != 0) {
  588.          printf("Could not seek to PCM sound data in \"%s\".\n", inPath);
  589.          exit(1);
  590.       }
  591.  
  592.       /* Declare sound file to have "infinite" number of samples. */
  593.       *num_samples = MAX_U_32_NUM;
  594.  
  595.    }
  596.  
  597. }
  598.  
  599. /************************************************************************
  600. /*
  601. /* print_config
  602. /*
  603. /* PURPOSE:  Prints the encoding parameters used
  604. /*
  605. /************************************************************************/
  606.  
  607. void
  608. print_config(fr_ps, psy, num_samples, inPath, outPath)
  609. frame_params *fr_ps;
  610. int     *psy;
  611. unsigned long *num_samples;
  612. char    inPath[MAX_NAME_SIZE];
  613. char    outPath[MAX_NAME_SIZE];
  614. {
  615.  layer *info = fr_ps->header;
  616.  
  617.    printf("Encoding configuration:\n");
  618.    if(info->mode != MPG_MD_JOINT_STEREO)
  619.       printf("Layer=%s   mode=%s   extn=%d   psy model=%d\n",
  620.              layer_names[info->lay-1], mode_names[info->mode],
  621.              info->mode_ext, *psy);
  622.    else printf("Layer=%s   mode=%s   extn=data dependant   psy model=%d\n",
  623.                layer_names[info->lay-1], mode_names[info->mode], *psy);
  624.    printf("samp frq=%.1f kHz   total bitrate=%d kbps\n",
  625.           s_freq[info->sampling_frequency],
  626.           bitrate[info->lay-1][info->bitrate_index]);
  627.    printf("de-emph=%d   c/right=%d   orig=%d   errprot=%d\n",
  628.           info->emphasis, info->copyright, info->original,
  629.           info->error_protection);
  630.    printf("input file: '%s'   output file: '%s'\n", inPath, outPath);
  631. }
  632.  
  633. /************************************************************************
  634. /*
  635. /* main
  636. /*
  637. /* PURPOSE:  MPEG I Encoder supporting layers 1 and 2, and
  638. /* psychoacoustic models 1 (MUSICAM) and 2 (AT&T)
  639. /*
  640. /* SEMANTICS:  One overlapping frame of audio of up to 2 channels are
  641. /* processed at a time in the following order:
  642. /* (associated routines are in parentheses)
  643. /*
  644. /* 1.  Filter sliding window of data to get 32 subband
  645. /* samples per channel.
  646. /* (window_subband,filter_subband)
  647. /*
  648. /* 2.  If joint stereo mode, combine left and right channels
  649. /* for subbands above #jsbound#.
  650. /* (*_combine_LR)
  651. /*
  652. /* 3.  Calculate scalefactors for the frame, and if layer 2,
  653. /* also calculate scalefactor select information.
  654. /* (*_scale_factor_calc)
  655. /*
  656. /* 4.  Calculate psychoacoustic masking levels using selected
  657. /* psychoacoustic model.
  658. /* (*_Psycho_One, psycho_anal)
  659. /*
  660. /* 5.  Perform iterative bit allocation for subbands with low
  661. /* mask_to_noise ratios using masking levels from step 4.
  662. /* (*_main_bit_allocation)
  663. /*
  664. /* 6.  If error protection flag is active, add redundancy for
  665. /* error protection.
  666. /* (*_CRC_calc)
  667. /*
  668. /* 7.  Pack bit allocation, scalefactors, and scalefactor select
  669. /* information (layer 2) onto bitstream.
  670. /* (*_encode_bit_alloc,*_encode_scale,II_transmission_pattern)
  671. /*
  672. /* 8.  Quantize subbands and pack them into bitstream
  673. /* (*_subband_quantization, *_sample_encoding)
  674. /*
  675. /************************************************************************/
  676.  
  677. main(argc, argv)
  678. int     argc;
  679. char    **argv;
  680. {
  681. typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT];
  682.     SBS  FAR        *sb_sample;
  683. typedef double JSBS[3][SCALE_BLOCK][SBLIMIT];
  684.     JSBS FAR        *j_sample;
  685. typedef double IN[2][HAN_SIZE];
  686.     IN   FAR        *win_que;
  687. typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT];
  688.     SUB  FAR        *subband;
  689.  
  690.     frame_params fr_ps;
  691.     layer info;
  692.     char original_file_name[MAX_NAME_SIZE];
  693.     char encoded_file_name[MAX_NAME_SIZE];
  694.     short FAR **win_buf;
  695. static short FAR buffer[2][1152];
  696. static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT];
  697. static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT];
  698. static double FAR ltmin[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT];
  699.     FLOAT snr32[32];
  700.     short sam[2][1056];
  701.     int whole_SpF, extra_slot = 0;
  702.     double avg_slots_per_frame, frac_SpF, slot_lag;
  703.     int model, stereo, error_protection;
  704. static unsigned int crc;
  705.     int i, j, k, adb;
  706.     unsigned long bitsPerSlot, samplesPerFrame, frameNum = 0;
  707.     unsigned long frameBits, sentBits = 0;
  708.     unsigned long num_samples;
  709. #ifdef UNIX
  710.     clock_t time_to_encode;
  711. #endif
  712. #ifdef  MACINTOSH
  713.     console_options.nrows = MAC_WINDOW_SIZE;
  714.     argc = ccommand(&argv);
  715. #endif
  716.  
  717.  
  718.     /* Most large variables are declared dynamically to ensure
  719.        compatibility with smaller machines */
  720.  
  721.     sb_sample = (SBS FAR *) mem_alloc(sizeof(SBS), "sb_sample");
  722.     j_sample = (JSBS FAR *) mem_alloc(sizeof(JSBS), "j_sample");
  723.     win_que = (IN FAR *) mem_alloc(sizeof(IN), "Win_que");
  724.     subband = (SUB FAR *) mem_alloc(sizeof(SUB),"subband");
  725.     win_buf = (short FAR **) mem_alloc(sizeof(short *)*2, "win_buf");
  726.  
  727.     /* clear buffers */
  728.     memset((char *) buffer, 0, sizeof(buffer));
  729.     memset((char *) bit_alloc, 0, sizeof(bit_alloc));
  730.     memset((char *) scalar, 0, sizeof(scalar));
  731.     memset((char *) j_scale, 0, sizeof(j_scale));
  732.     memset((char *) scfsi, 0, sizeof(scfsi));
  733.     memset((char *) ltmin, 0, sizeof(ltmin));
  734.     memset((char *) lgmin, 0, sizeof(lgmin));
  735.     memset((char *) max_sc, 0, sizeof(max_sc));
  736.     memset((char *) snr32, 0, sizeof(snr32));
  737.     memset((char *) sam, 0, sizeof(sam));
  738.  
  739.     fr_ps.header = &info;
  740.     fr_ps.tab_num = -1;             /* no table loaded */
  741.     fr_ps.alloc = NULL;
  742.     info.version = MPEG_AUDIO_ID;
  743.  
  744.     programName = argv[0];
  745.     if(argc==1)     /* no command-line args */
  746.        obtain_parameters(&fr_ps, &model, &num_samples,
  747.                          original_file_name, encoded_file_name);
  748.     else
  749.        parse_args(argc, argv, &fr_ps, &model, &num_samples,
  750.                   original_file_name, encoded_file_name);
  751.     print_config(&fr_ps, &model, &num_samples,
  752.                  original_file_name, encoded_file_name);
  753.  
  754. #ifdef UNIX
  755.     time_to_encode = clock();
  756. #endif
  757.  
  758.  
  759.     hdr_to_frps(&fr_ps);
  760.     stereo = fr_ps.stereo;
  761.     error_protection = info.error_protection;
  762.  
  763.     if (info.lay == 1) { bitsPerSlot = 32; samplesPerFrame = 384;  }
  764.     else               { bitsPerSlot = 8;  samplesPerFrame = 1152; }
  765.     /* Figure average number of 'slots' per frame. */
  766.     /* Bitrate means TOTAL for both channels, not per side. */
  767.     avg_slots_per_frame = ((double)samplesPerFrame /
  768.                            s_freq[info.sampling_frequency]) *
  769.                           ((double)bitrate[info.lay-1][info.bitrate_index] /
  770.                            (double)bitsPerSlot);
  771.     whole_SpF = (int) avg_slots_per_frame;
  772.     printf("slots/frame = %d\n",whole_SpF);
  773.     frac_SpF  = avg_slots_per_frame - (double)whole_SpF;
  774.     slot_lag  = -frac_SpF;
  775.     printf("frac SpF=%.3f, tot bitrate=%d kbps, s freq=%.1f kHz\n",
  776.            frac_SpF, bitrate[info.lay-1][info.bitrate_index],
  777.            s_freq[info.sampling_frequency]);
  778.  
  779.     if (frac_SpF != 0)
  780.        printf("Fractional number of slots, padding required\n");
  781.     else info.padding = 0;
  782.  
  783.     while (get_audio(musicin, buffer, num_samples, stereo, info.lay) > 0) {
  784.  
  785.        fprintf(stderr, "{%4lu}\r", frameNum++); fflush(stderr);
  786.        win_buf[0] = &buffer[0][0];
  787.        win_buf[1] = &buffer[1][0];
  788.        if (frac_SpF != 0) {
  789.           if (slot_lag > (frac_SpF-1.0) ) {
  790.              slot_lag -= frac_SpF;
  791.              extra_slot = 0;
  792.              info.padding = 0;
  793.              /*  printf("No padding for this frame\n"); */
  794.           }
  795.           else {
  796.              extra_slot = 1;
  797.              info.padding = 1;
  798.              slot_lag += (1-frac_SpF);
  799.              /*  printf("Padding for this frame\n");    */
  800.           }
  801.        }
  802.        adb = (whole_SpF+extra_slot) * bitsPerSlot;
  803.  
  804.        switch (info.lay) {
  805.  
  806. /***************************** Layer I **********************************/
  807.  
  808.           case 1 :
  809.              for (j=0;j<SCALE_BLOCK;j++)
  810.              for (k=0;k<stereo;k++) {
  811.                 window_subband(&win_buf[k], &(*win_que)[k][0], k);
  812.                 filter_subband(&(*win_que)[k][0], &(*sb_sample)[k][0][j][0]);
  813.              }
  814.  
  815.              I_scale_factor_calc(*sb_sample, scalar, stereo);
  816.              if(fr_ps.actual_mode == MPG_MD_JOINT_STEREO) {
  817.                 I_combine_LR(*sb_sample, *j_sample);
  818.                 I_scale_factor_calc(j_sample, &j_scale, 1);
  819.              }
  820.  
  821.              put_scale(scalar, &fr_ps, max_sc);
  822.  
  823.              if (model == 1) I_Psycho_One(buffer, max_sc, ltmin, &fr_ps);
  824.              else {
  825.                 for (k=0;k<stereo;k++) {
  826.                    psycho_anal(&buffer[k][0],&sam[k][0], k, info.lay, snr32,
  827.                                (FLOAT)s_freq[info.sampling_frequency]*1000);
  828.                    for (i=0;i<SBLIMIT;i++) ltmin[k][i] = (double) snr32[i];
  829.                 }
  830.              }
  831.  
  832.              I_main_bit_allocation(ltmin, bit_alloc, &adb, &fr_ps);
  833.  
  834.              if (error_protection) I_CRC_calc(&fr_ps, bit_alloc, &crc);
  835.  
  836.              encode_info(&fr_ps, &bs);
  837.  
  838.              if (error_protection) encode_CRC(crc, &bs);
  839.  
  840.              I_encode_bit_alloc(bit_alloc, &fr_ps, &bs);
  841.              I_encode_scale(scalar, bit_alloc, &fr_ps, &bs);
  842.              I_subband_quantization(scalar, *sb_sample, j_scale, *j_sample,
  843.                                     bit_alloc, *subband, &fr_ps);
  844.              I_sample_encoding(*subband, bit_alloc, &fr_ps, &bs);
  845.              for (i=0;i<adb;i++) put1bit(&bs, 0);
  846.           break;
  847.  
  848. /***************************** Layer 2 **********************************/
  849.  
  850.           case 2 :
  851.              for (i=0;i<3;i++) for (j=0;j<SCALE_BLOCK;j++)
  852.                 for (k=0;k<stereo;k++) {
  853.                    window_subband(&win_buf[k], &(*win_que)[k][0], k);
  854.                    filter_subband(&(*win_que)[k][0], &(*sb_sample)[k][i][j][0]);
  855.                 }
  856.  
  857.                 II_scale_factor_calc(*sb_sample, scalar, stereo, fr_ps.sblimit);
  858.                 pick_scale(scalar, &fr_ps, max_sc);
  859.                 if(fr_ps.actual_mode == MPG_MD_JOINT_STEREO) {
  860.                    II_combine_LR(*sb_sample, *j_sample, fr_ps.sblimit);
  861.                    II_scale_factor_calc(j_sample, &j_scale, 1, fr_ps.sblimit);
  862.                 }       /* this way we calculate more mono than we need */
  863.                         /* but it is cheap */
  864.  
  865.                 if (model == 1) II_Psycho_One(buffer, max_sc, ltmin, &fr_ps);
  866.                 else {
  867.                    for (k=0;k<stereo;k++) {
  868.                       psycho_anal(&buffer[k][0],&sam[k][0], k, 
  869.                                  info.lay, snr32,
  870.                                  (FLOAT)s_freq[info.sampling_frequency]*1000);
  871.                       for (i=0;i<SBLIMIT;i++) ltmin[k][i] = (double) snr32[i];
  872.                    }
  873.                 }
  874.  
  875.                 II_transmission_pattern(scalar, scfsi, &fr_ps);
  876.                 II_main_bit_allocation(ltmin, scfsi, bit_alloc, &adb, &fr_ps);
  877.  
  878.                 if (error_protection)
  879.                    II_CRC_calc(&fr_ps, bit_alloc, scfsi, &crc);
  880.  
  881.                 encode_info(&fr_ps, &bs);
  882.  
  883.                 if (error_protection) encode_CRC(crc, &bs);
  884.  
  885.                 II_encode_bit_alloc(bit_alloc, &fr_ps, &bs);
  886.                 II_encode_scale(bit_alloc, scfsi, scalar, &fr_ps, &bs);
  887.                 II_subband_quantization(scalar, *sb_sample, j_scale,
  888.                                       *j_sample, bit_alloc, *subband, &fr_ps);
  889.                 II_sample_encoding(*subband, bit_alloc, &fr_ps, &bs);
  890.                 for (i=0;i<adb;i++) put1bit(&bs, 0);
  891.           break;
  892.  
  893. /***************************** Layer 3 **********************************/
  894.  
  895.           case 3 : break;
  896.  
  897.        }
  898.  
  899.        frameBits = sstell(&bs) - sentBits;
  900.        if(frameBits%bitsPerSlot)   /* a program failure */
  901.           fprintf(stderr,"Sent %ld bits = %ld slots plus %ld\n",
  902.                   frameBits, frameBits/bitsPerSlot,
  903.                   frameBits%bitsPerSlot);
  904.        sentBits += frameBits;
  905.  
  906.     }
  907.  
  908.     close_bit_stream_w(&bs);
  909.  
  910.     printf("Avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
  911.            (FLOAT) sentBits / (frameNum * bitsPerSlot),
  912.            (FLOAT) sentBits / (frameNum * samplesPerFrame),
  913.            (FLOAT) sentBits / (frameNum * samplesPerFrame) *
  914.            s_freq[info.sampling_frequency]);
  915.  
  916.     if (fclose(musicin) != 0){
  917.        printf("Could not close \"%s\".\n", original_file_name);
  918.        exit(2);
  919.     }
  920.  
  921. #ifdef  MACINTOSH
  922.     set_mac_file_attr(encoded_file_name, VOL_REF_NUM, CREATOR_ENCODE,
  923.                       FILETYPE_ENCODE);
  924. #endif
  925.  
  926.     printf("Encoding of \"%s\" with psychoacoustic model %d is finished\n",
  927.            original_file_name, model);
  928.     printf("The MPEG encoded output file name is \"%s\"\n",
  929.             encoded_file_name);
  930.  
  931. #ifdef UNIX
  932.     time_to_encode = clock()-time_to_encode;
  933.  
  934.     printf("Total time used to encode the stream was %.2f secs.\n",
  935.     (float)time_to_encode/CLK_TCK);
  936. #endif
  937.  
  938.     exit(0);
  939. }
  940.  
  941. /************************************************************************
  942. /*
  943. /* usage
  944. /*
  945. /* PURPOSE:  Writes command line syntax to the file specified by #stderr#
  946. /*
  947. /************************************************************************/
  948.  
  949. //static void usage()  /* print syntax & exit */
  950. void usage()  /* print syntax & exit */
  951. {
  952.     fprintf(stderr,
  953.     "usage: %s                         queries for all arguments, or\n",
  954.             programName);
  955.     fprintf(stderr,
  956.     "       %s [-l lay][-m mode][-p psy][-s sfrq][-b br][-d emp]\n",
  957.             programName);
  958.     fprintf(stderr,
  959.     "          [-c][-o][-e][-i] inputPCM [outBS]\n");
  960.     fprintf(stderr,"where\n");
  961.     fprintf(stderr," -l lay   use layer <lay> coding   (dflt %4u)\n",DFLT_LAY);
  962.     fprintf(stderr," -m mode  channel mode : s/d/j/m   (dflt %4c)\n",DFLT_MOD);
  963.     fprintf(stderr," -p psy   psychoacoustic model 1/2 (dflt %4u)\n",DFLT_PSY);
  964.     fprintf(stderr," -s sfrq  input smpl rate in kHz   (dflt %4.1f)\n",DFLT_SFQ);
  965.     fprintf(stderr," -b br    total bitrate in kbps    (dflt %4u)\n",DFLT_BRT);
  966.     fprintf(stderr," -d emp   de-emphasis n/5/c        (dflt %4c)\n",DFLT_EMP);
  967.     fprintf(stderr," -c       mark as copyright\n");
  968.     fprintf(stderr," -o       mark as original\n");
  969.     fprintf(stderr," -e       add error protection\n");
  970.     fprintf(stderr," -i       set private bit\n");
  971.     fprintf(stderr," inputPCM input PCM sound file (standard or AIFF)\n");
  972.     fprintf(stderr," outBS    output bit stream of encoded audio (dflt inName+%s)\n",
  973.             DFLT_EXT);
  974.     exit(1);
  975. }
  976.  
  977. /************************************************************************
  978. /*
  979. /* aiff_check
  980. /*
  981. /* PURPOSE:  Checks AIFF header information to make sure it is valid.
  982. /*           Exits if not.
  983. /*
  984. /************************************************************************/
  985.  
  986. void aiff_check(file_name, pcm_aiff_data)
  987. char *file_name;          /* Pointer to name of AIFF file */
  988. IFF_AIFF *pcm_aiff_data;  /* Pointer to AIFF data structure */
  989. {
  990.  
  991. #ifdef IFF_LONG
  992.     if (pcm_aiff_data->sampleType != IFF_ID_SSND) {
  993. #else
  994.     if (strncmp(&pcm_aiff_data->sampleType,IFF_ID_SSND,4)) {
  995. #endif
  996.        printf("Sound data is not PCM in \"%s\".\n", file_name);
  997.        exit(1);
  998.     }
  999.  
  1000.     if(SmpFrqIndex((long)pcm_aiff_data->sampleRate) < 0) {
  1001.        printf("in \"%s\".\n", file_name);
  1002.        exit(1);
  1003.     }
  1004.  
  1005.     if (pcm_aiff_data->sampleSize != sizeof(short) * BITS_IN_A_BYTE) {
  1006.         printf("Sound data is not %d bits in \"%s\".\n",
  1007.                sizeof(short) * BITS_IN_A_BYTE, file_name);
  1008.         exit(1);
  1009.     }
  1010.  
  1011.     if (pcm_aiff_data->numChannels != MONO &&
  1012.         pcm_aiff_data->numChannels != STEREO) {
  1013.        printf("Sound data is not mono or stereo in \"%s\".\n", file_name);
  1014.        exit(1);
  1015.     }
  1016.  
  1017.     if (pcm_aiff_data->blkAlgn.blockSize != 0) {
  1018.        printf("Block size is not %lu bytes in \"%s\".\n", 0, file_name);
  1019.        exit(1);
  1020.     }
  1021.  
  1022.     if (pcm_aiff_data->blkAlgn.offset != 0) {
  1023.        printf("Block offset is not %lu bytes in \"%s\".\n", 0, file_name);
  1024.        exit(1);
  1025.     }
  1026.  
  1027. }
  1028.